import Vue from 'vue/dist/vue.runtime.esm'
//import Vue from 'vue'
//import Vue from 'vue/dist/vue'
import Home from './RedisConsole'

import router from "./index"
Vue.use(router)

import store from "./store"
Vue.use(store)

import ElementUi from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUi);


//  引入 antd-vue版本
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
Vue.use(Antd)

// import {Form} from 'ant-design-vue';
// Vue.prototype.$form = Form;

//  引入自定义的css
import '../../base/base.css'

import cache from "../../base/local_cache"
import event from "../../base/event_loop"
import Listener from "../../base/listen"
import cst from "../../base/cst"
import TimerTask from '../../base/timer'
import ajax from '../../base/ajax'
/**
 *  cache       本地缓存
 *  event       事件管理者
 *  map         线上缓存
 *  listener    用于登录的 监听者
 */
Vue.prototype.$cache = cache;
Vue.prototype.$event = event;
Vue.prototype.$map = new Map();
//  初始化为登录中这种状态  需要token相关的页面，在创建的时候 需要判定这个状态
Vue.prototype.$listener = new Listener(cst.$login.inLogin);
//  定时调度器
Vue.prototype.$timer = new TimerTask(5000);

//  注册组件
//import Text0 from "../../components/page/Text0"
//Vue.component("wText",Text0)
// import components0 from '../../components/page/plugin';
// Vue.use(components0)

//  antd 国际化
import 'moment/locale/zh-cn';


//  京东移动ui
import NutUI from '@nutui/nutui';
import '@nutui/nutui/dist/nutui.css';
NutUI.install(Vue);

let vue = new Vue({
    store,
    router,
    render: h => h(Home),
    created() {
        //  在这里取值环境变量
        ajax.host = process.env.VUE_APP_HOST;
    }
})
vue.$mount("#app");

ajax.setVue(vue);

vue.$message.config({
    top: `100px`,
    duration: 2,
    maxCount: 3,
});

Vue.prototype.$show = function (msg, type) {
    if(type == null){
        type = 'info';
    }
    vue.$message[type](msg)
};

Vue.prototype.$aShow = function (msg, type) {
    if(type == null){
        type = 'info';
    }
    vue.$message[type](msg)
};

//  如果登录状态发生了改变 在这里进行订正  调整$listener中的状态 其他页面根据这个状态
//  这里是不需要取消注册 ，这里是最大的生命周期
//  只在这里处理用户登录成功的全局逻辑
event.register("main.js",{
    listen:[cst.$ajax.login,cst.$ajax.login1,cst.$ajax.login2],
    callback(event){
        let r = event.data.data;
        if(r.code == 0){
            switch (event.type){
                case cst.$ajax.login:
                case cst.$ajax.login1:
                case cst.$ajax.login2:
                    //  保存登录用户
                    let originUser = vue.$map.get("loginUser");
                    //  添加token信息
                    Object.assign(originUser,r.data);
                    //  先设置好数据 在发布登录信息  后续会使用到这个数据
                    ajax.setUser(originUser);
                    vue.$cache.putLoginUser(originUser)

                    //  如果是刷新token的级别 就不要发送事件了
                    if(event.type != cst.$ajax.login2){
                        vue.$listener.publish(cst.$login.login)
                    }
                    vue.$store.state.user.status = cst.$ajax.login;
                    vue.$store.state.user.loginUser = originUser;

                    //  链接ws
                    vue.$ws.connect(originUser.accessToken);

                    //  加载一遍用户明细信息
                    ajax.postWithToken("/user/oauth/token.skip/do?api=info",{},cst.$ajax.info)
                    break;

                case cst.$ajax.info:
                    //  加载明细信息
                    vue.$userDetail = JSON.parse(JSON.stringify(r.data));
                    break;
            }
        }else{
            vue.$listener.publish(cst.$login.noLogin)
        }
    }
})

//  设置定时巡检
vue.$timer.start();
vue.$timer.register("main.js",{
    check(){
        //console.log("timer timer timer")
        //  检查登录的token信息
        if(vue.$store.state.user.status == cst.$ajax.login){
            //  如果token过期了 那么重新加载一次token
            let u = vue.$store.state.user.loginUser;
            let s = Math.floor(new Date(u.accessTokenCreateTime).valueOf() / 1000);
            let e = Math.floor(new Date().valueOf() / 1000);

            //  定时检查并且登录
            if(e -s >= u.expire ){
                console.log("token已经过期，重新登录中")
                //  刷新token
                let loginUser = cache.getLoginUser();
                if(loginUser != null){
                    let u0 = {
                        username:loginUser.username,
                        password:loginUser.password,
                        grantType:"password"
                    }
                    ajax.login("/user/oauth/token.skip?api=token",u0,cst.$ajax.login2)
                    vue.$map.set("loginUser",u0);
                }else{
                    //  设置成不登陆
                    vue.$listener.publish(cst.$login.noLogin)
                }
            }
        }
    }
})

//  生成唯一ID
Vue.prototype.uniqueId = 1;
Vue.prototype.$getUniqueId = function(){
    let id = this.uniqueId++;
    return "id_ksv"+id;
}

//  添加一个copy函数 (深复制 - 暂时使用json的方式)  ,可以通过递推的方式
Vue.prototype.$copy = (obj) => {
    let rtn = JSON.parse(JSON.stringify(obj));
    return rtn;
}

//  将数组根据指定的字段转换成map
Vue.prototype.$toMap = (list,key) => {
    let map = new Map();
    list.forEach(item => {
        map.set(item[key],item)
    })
}

Vue.component('system_create', {
    render: function (createElement) {
        //console.log(this.node)
        return createElement(
            this.nodeName,   // 标签名称
            this.$slots.default
        )
    },
    props: {
        nodeName: {
            type: String,
            required: true
        },
        node:{
            type:Object||null
        }
    }
});


//  路由守卫 token校验
router.beforeEach((to,from,next) => {
    //  如果没有匹配任何路由，跳转到登录页面
    if(to.matched.length == 0){
        next({
            path:"/login",
            replace:true
        })
        return ;
    }
    if(to.fullPath != null && to.fullPath.startsWith("/auth")){
        let user = store.state.user
        if(user.status == cst.$ajax.noLogin){
            next({
                path:"/login",
                replace:true
            })
        }else{
            next();
        }
    }else{
        next();
    }
})

//  获取选中的文本
Vue.prototype.$getSelectText = () => {
    return document.getSelection().toString();
}


//  监听系统的按钮 同时对外分发事件    统一的分发事件
let originKeyEvent = document.onkeydown;
document.onkeydown = (e) => {
    let event0 = {
        type:"keyDown",
        data:e
    }

    //  如果存在监听的操作  那么 过滤掉系统的操作  ????
    if(event.publishEvent(event0)){
        //
    }


    if(originKeyEvent){
        originKeyEvent(arguments);
    }
}